package com.hhkj.admin.sale.service.base.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hhkj.admin.sale.common.cont.SaleAccountConst;
import com.hhkj.admin.sale.common.cont.SaleCommissionConst;
import com.hhkj.admin.sale.domain.SaleAccount;
import com.hhkj.admin.sale.domain.SaleCommission;
import com.hhkj.admin.sale.mapper.SaleAccountMapper;
import com.hhkj.admin.sale.model.dopo.SaleAccountDo;
import com.hhkj.admin.sale.model.dopo.SaleAccountPo;
import com.hhkj.admin.sale.service.base.SaleAccountService;
import com.ruoyi.common.base.biz.service.base.BaseServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author admin
 */
@Service
public class SaleAccountServiceImpl
        extends BaseServiceImpl<SaleAccount, SaleAccountDo, SaleAccountPo, SaleAccountMapper>
        implements SaleAccountService {

    @Override
    public SaleAccountPo getPoBySaleId(Long saleId) {
        return getBaseMapper().getPoBySaleId(saleId);
    }

    @Override
    public synchronized SaleAccount initAccount(Long saleId) {
        // 1、根据saleId获取账户信息
        LambdaQueryWrapper<SaleAccount> accountQuery = new LambdaQueryWrapper<>();
        accountQuery.eq(SaleAccount::getSaleId, saleId);

        SaleAccount account = this.getOne(accountQuery, false);
        if (ObjectUtil.isNotNull(account)) {
            return account;
        }
        SaleAccount accountDo
                = new SaleAccount(BigDecimal.ZERO, BigDecimal.ZERO, 0, BigDecimal.ZERO, saleId);
        accountDo.setCreateBy(saleId);
        this.save(accountDo);
        return accountDo;
    }

    @Override
    public SaleAccount getBySaleId(Long saleId) {
        // 1、根据saleId获取账户信息
        SaleAccount account = this.getPoBySaleId(saleId);
        if (ObjectUtil.isNull(account)) {
            account = this.initAccount(saleId);
        }
        return account;
    }

    @Override
    public boolean addTotalPrice(Long saleId, BigDecimal price) {
        return commonAtomicUpdate(saleId, price, SaleAccountConst.UpdateField.TOTAL_PRICE, SaleAccountConst.UpdateMethod.ADD);
    }

    @Override
    public boolean subTotalPrice(Long saleId, BigDecimal price) {
        return commonAtomicUpdate(saleId, price, SaleAccountConst.UpdateField.TOTAL_PRICE, SaleAccountConst.UpdateMethod.SUB);
    }

    @Override
    public boolean addBalanceByCommissionBatch(List<? extends SaleCommission> saleCommissionList) {
        saleCommissionList.forEach(saleCommission -> addBalance(saleCommission.getSaleId(), saleCommission.getPrice()));
        return true;
    }

    @Override
    public boolean addBalance(Long saleId, BigDecimal price) {
        return commonAtomicUpdate(saleId, price, SaleAccountConst.UpdateField.BALANCE_PRICE, SaleAccountConst.UpdateMethod.ADD);
    }

    @Override
    public boolean subBalance(Long saleId, BigDecimal price) {
        return commonAtomicUpdate(saleId, price, SaleAccountConst.UpdateField.BALANCE_PRICE, SaleAccountConst.UpdateMethod.SUB);
    }

    @Override
    public boolean incInvitation(Long saleId) {
        return commonAtomicUpdate(saleId, new BigDecimal("1"), SaleAccountConst.UpdateField.INVITED_AMOUNT, SaleAccountConst.UpdateMethod.ADD);
    }

    private boolean commonAtomicUpdate(Long saleId,
                                 BigDecimal inc,
                                 SaleAccountConst.UpdateField updateField,
                                 SaleAccountConst.UpdateMethod updateMethod) {
        LambdaUpdateWrapper<SaleAccount> updateWrapper = new LambdaUpdateWrapper<SaleAccount>().eq(SaleAccount::getSaleId, saleId);
        updateWrapper = addAtomicUpdate(updateWrapper, inc, updateField, updateMethod);
        return update(updateWrapper);
    }

    public LambdaUpdateWrapper<SaleAccount> addAtomicUpdate(LambdaUpdateWrapper<SaleAccount> updateWrapper,
                                                             BigDecimal inc,
                                                             SaleAccountConst.UpdateField updateField,
                                                             SaleAccountConst.UpdateMethod updateMethod) {
        return updateWrapper.setSql(updateField.getCode() + " = " + updateField.getCode() + updateMethod.getCode() + inc);
    }
}




